#if PLATFORM == PLATFORM_WIN32
//#	define GLEW_STATIC
#	include "glew/glew.h"
#	include "glew/wglew.h"
#endif
#include "mathlib/vec3.h"
#include "mathlib/vec4.h"
#include "mathlib/mathlib.h"
#include "kernel/debug.h"
#include "vertexbuffersdl.h"

namespace rengine3d {

	CVertexBufferSDL::CVertexBufferSDL(IRenderDriver* renderDriver, uint flags, 
		vbDrawType_t drawType, vbUsageType_t usageType, uint vertexNum, uint indexNum): IVertexBuffer(renderDriver, flags, drawType, usageType, vertexNum, indexNum) {
	}

	CVertexBufferSDL::~CVertexBufferSDL() {
		for( uint i=0; i < vbNumVertexFlags; i++) {
			m_vertexArray[i].clear();
		}

		m_indexArray.clear();
	}

	void CVertexBufferSDL::AddVertex(const CVec3& vertex, uint flags) {
		int i = Log2Int((int)flags);

		m_vertexArray[i].push_back(vertex.x);
		m_vertexArray[i].push_back(vertex.y);
		m_vertexArray[i].push_back(vertex.z);
	}

	void CVertexBufferSDL::AddColor(const CVec4& color, uint flags) {
		int i = Log2Int((int)flags);

		m_vertexArray[i].push_back(color.x);
		m_vertexArray[i].push_back(color.y);
		m_vertexArray[i].push_back(color.z);
		m_vertexArray[i].push_back(color.w);
	}

	void CVertexBufferSDL::AddIndex(uint index) {
		m_indexArray.push_back(index);
	}

	void CVertexBufferSDL::Compile(uint flags) {
	}

	void CVertexBufferSDL::Transform(const CMat4& transformMatrix) {
	}

	void CVertexBufferSDL::Draw(vbDrawType_t drawType ) {
		GLenum mode = GL_TRIANGLES;

		switch (drawType) {
		case vbDrawType_Quad:	mode = GL_QUADS;
		case vbDrawType_Line:	mode = GL_LINE_STRIP;
		case vbDrawType_Point:	mode = GL_POINTS;			
		};

		int size = m_numElements;
		if (m_numElements <= 0) {
			size = GetIndexNum();
		}

		glDrawElements(mode, size, GL_UNSIGNED_INT, &m_indexArray[0]);
	}

	void CVertexBufferSDL::DrawIndices(uint* indices, uint count, vbDrawType_t drawType) {
		GLenum mode = GL_TRIANGLES;

		switch (drawType) {
		case vbDrawType_Quad:	mode = GL_QUADS;
		case vbDrawType_Line:	mode = GL_LINE_STRIP;
		case vbDrawType_Point:	mode = GL_POINTS;			
		};

		glDrawElements(mode, count, GL_UNSIGNED_INT, indices);
	}

	void CVertexBufferSDL::Bind(void) {
	}

	void CVertexBufferSDL::UnBind(void) {
	}

	void CVertexBufferSDL::SetVertexStates(uint flags) {
		if (flags & vbFlag_Position){
			glEnableClientState(GL_VERTEX_ARRAY);
			int i = Log2Int(vbFlag_Position);
			glVertexPointer(vertexElements[i], GL_FLOAT, sizeof(float) * vertexElements[i], &m_vertexArray[i][0]);
		} else {
			glDisableClientState(GL_VERTEX_ARRAY);
		}

		if (flags & vbFlag_Color){
			glEnableClientState(GL_COLOR_ARRAY);
			int i = Log2Int(vbFlag_Color);
			glVertexPointer(vertexElements[i], GL_FLOAT, sizeof(float) * vertexElements[i], &m_vertexArray[i][0]);
		} else {
			glDisableClientState(GL_COLOR_ARRAY);
		}

		if (flags & vbFlag_Normal){
			glEnableClientState(GL_NORMAL_ARRAY);
			int i = Log2Int(vbFlag_Normal);
			glVertexPointer(vertexElements[i], GL_FLOAT, sizeof(float) * vertexElements[i], &m_vertexArray[i][0]);
		} else {
			glDisableClientState(GL_NORMAL_ARRAY);
		}

		if (flags & vbFlag_Texture0){
			glClientActiveTextureARB(GL_TEXTURE0_ARB);
			glEnableClientState(GL_TEXTURE_COORD_ARRAY);
			int i = Log2Int(vbFlag_Texture0);
			glVertexPointer(vertexElements[i], GL_FLOAT, sizeof(float) * vertexElements[i], &m_vertexArray[i][0]);
		} else {
			glClientActiveTextureARB(GL_TEXTURE0_ARB);
			glDisableClientState(GL_TEXTURE_COORD_ARRAY);
		}

		if (flags & vbFlag_Texture1){
			glClientActiveTextureARB(GL_TEXTURE1_ARB);
			glEnableClientState(GL_TEXTURE_COORD_ARRAY);
			int i = Log2Int(vbFlag_Texture1);
			glVertexPointer(vertexElements[i], GL_FLOAT, sizeof(float) * vertexElements[i], &m_vertexArray[i][0]);
		} else {
			glClientActiveTextureARB(GL_TEXTURE1_ARB);
			glDisableClientState(GL_TEXTURE_COORD_ARRAY);
		}

		if (flags & vbFlag_Texture2){
			glClientActiveTextureARB(GL_TEXTURE2_ARB);
			glEnableClientState(GL_TEXTURE_COORD_ARRAY);
			int i = Log2Int(vbFlag_Texture2);
			glVertexPointer(vertexElements[i], GL_FLOAT, sizeof(float) * vertexElements[i], &m_vertexArray[i][0]);
		} else {
			glClientActiveTextureARB(GL_TEXTURE2_ARB);
			glDisableClientState(GL_TEXTURE_COORD_ARRAY);
		}

		if (flags & vbFlag_Texture3){
			glClientActiveTextureARB(GL_TEXTURE3_ARB);
			glEnableClientState(GL_TEXTURE_COORD_ARRAY);
			int i = Log2Int(vbFlag_Texture3);
			glVertexPointer(vertexElements[i], GL_FLOAT, sizeof(float) * vertexElements[i], &m_vertexArray[i][0]);
		} else {
			glClientActiveTextureARB(GL_TEXTURE3_ARB);
			glDisableClientState(GL_TEXTURE_COORD_ARRAY);
		}

		if (flags & vbFlag_Texture4){
			glClientActiveTextureARB(GL_TEXTURE4_ARB);
			glEnableClientState(GL_TEXTURE_COORD_ARRAY);
			int i = Log2Int(vbFlag_Texture4);
			glVertexPointer(vertexElements[i], GL_FLOAT, sizeof(float) * vertexElements[i], &m_vertexArray[i][0]);
		} else {
			glClientActiveTextureARB(GL_TEXTURE4_ARB);
			glDisableClientState(GL_TEXTURE_COORD_ARRAY);
		}
	}

	float* CVertexBufferSDL::GetArray(uint arrayType) {
		int i = Log2Int(arrayType);

		return &m_vertexArray[i][0];
	}

	uint* CVertexBufferSDL::GetIndexArray() {
		return &m_indexArray[0];
	}

	uint CVertexBufferSDL::GetVertexNum(void) {
		int i = Log2Int((int)vbFlag_Position);
		uint size = m_vertexArray[i].size() / vertexElements[i];

		return size;
	}

	uint CVertexBufferSDL::GetIndexNum(void) {
		return m_indexArray.size();
	}

}